home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / chtiff / source / chtiff1.c next >
Text File  |  1993-07-08  |  11KB  |  435 lines

  1. /*
  2. TownsTIFF ←→ NeXTTIFF コンバーター
  3. ファイル読み込み部分
  4. */
  5.  
  6. #include<stdio.h>
  7. #include<stdlib.h>
  8. #include"define.h"
  9. #define READ_SECTION 1
  10. #include"function.h"
  11.  
  12.  
  13. /*
  14. offset=0なら、現在のファイルポインタから読む。
  15. ちなみにここは、モトローラ・Intel形式を吸収する役目もあります。
  16. */
  17. unsigned char read_BYTE(unsigned long offset)
  18. {
  19.     unsigned long backup_offset;
  20.     unsigned char ret;
  21.  
  22.     if(offset){
  23.         backup_offset=ftell(from.fp);
  24.         fseek(from.fp, offset, SEEK_SET);
  25.         }
  26.  
  27.     ret=fgetc(from.fp);
  28.  
  29.     if(offset) fseek(from.fp, backup_offset, SEEK_SET);
  30.     return(ret);
  31. }
  32.  
  33. unsigned short read_SHORT(unsigned long offset)
  34. {
  35.     unsigned long backup_offset;
  36.     unsigned short ret,ret2;
  37.  
  38.     if(offset){
  39.         backup_offset=ftell(from.fp);
  40.         fseek(from.fp, offset, SEEK_SET);
  41.         }
  42.  
  43.     ret =fgetc(from.fp);
  44.     ret2=fgetc(from.fp);
  45.  
  46.     if(from.Intel) ret |= (ret2<<8);
  47.               else ret = (ret<<8) | ret2;
  48.  
  49.     if(offset) fseek(from.fp, backup_offset, SEEK_SET);
  50.     return(ret);
  51. }
  52.  
  53. unsigned long read_LONG(unsigned long offset)
  54. {
  55.     unsigned long backup_offset;
  56.     unsigned long ret,a[4];
  57.  
  58.     if(offset){
  59.         backup_offset=ftell(from.fp);
  60.         fseek(from.fp, offset, SEEK_SET);
  61.         }
  62.  
  63.     a[0]=fgetc(from.fp);
  64.     a[1]=fgetc(from.fp);
  65.     a[2]=fgetc(from.fp);
  66.     a[3]=fgetc(from.fp);
  67.     
  68.     if(from.Intel) ret=( a[0] | (a[1]<<8) | (a[2]<<16) | (a[3]<<24) );
  69.               else ret=( a[3] | (a[2]<<8) | (a[1]<<16) | (a[0]<<24) );
  70.  
  71.     if(offset) fseek(from.fp, backup_offset, SEEK_SET);
  72.     return(ret);
  73. }
  74.  
  75. /* 
  76. 大きい型から小さい型へキャストする時は、下位バイトを取ると仮定している
  77. IFDのVALUE読み込みのみに使うこと
  78.  */
  79. unsigned long read_VALUE( unsigned short type, unsigned long offset )
  80. {
  81.     unsigned long ret;
  82.     switch( type ){
  83.         case BYTE_TYPE: case ASCII_TYPE:
  84.             ret = read_BYTE( offset );
  85.             fgetc(from.fp);fgetc(from.fp);fgetc(from.fp);
  86.             return( ret );
  87.         case SHORT_TYPE:
  88.             ret = read_SHORT( offset );
  89.             fgetc(from.fp);fgetc(from.fp);
  90.             return( ret );
  91.         case LONG_TYPE:
  92.             return( read_LONG( offset ) );
  93.         default:
  94.             puts("unexpected Rational type!");
  95.             exit(1);
  96.         }
  97. }
  98.  
  99.  
  100. /*
  101. Intelフォーマットかどうかを調べる関数。
  102. Mainに入れると変更がややこしくなりそうなので・・・
  103. */
  104. int isIntel(void)
  105. {
  106.     unsigned char first,second;
  107.  
  108.     fseek(from.fp, (unsigned long)0, SEEK_SET);
  109.     first=fgetc(from.fp); second=fgetc(from.fp);
  110.     from.Intel=-1;
  111.     if( (first=='I') && (second=='I') ) from.Intel=1;
  112.     if( (first=='M') && (second=='M') ) from.Intel=0;
  113.  
  114.     if( read_SHORT(0UL) == 0x2a ) return(1);
  115.     return(-1);    /* not TIFF file */
  116. }
  117.  
  118.  
  119.  
  120. /*
  121. IFD(Image File Directry) を読み込む。
  122. fpは予め、しかるべきところにセットされてること。
  123. */
  124. #include"color.h"
  125.  
  126. void read_IFD(void)
  127. {
  128.     unsigned int i,j,entry_num;
  129.     unsigned long offset,len, k;
  130.     unsigned short tag,type;
  131.     unsigned short *p;
  132.     unsigned long *pl;
  133.  
  134.     /* from の初期化 */
  135.     from.Image_Width =
  136.     from.Image_Length =
  137.     from.Bits_Per_Sample =
  138.     from.Compression =
  139.     from.Photo_Interp =
  140.     from.Fill_Order =
  141.     from.Samples_Per_Pixel =
  142.     from.Max_Sample_Value =
  143.     from.Planer_Config = 0;
  144.  
  145.     from.New_Subfile_Type =
  146.     from.X_Resolution.bunbo = from.X_Resolution.bunsi =
  147.     from.Y_Resolution.bunbo = from.Y_Resolution.bunsi =
  148.     from.Rows_Per_Strip = 0UL;
  149.  
  150.     from.Strip_Offset =from.Strips_ByteCount = NULL;
  151.     from.RED = from.GREEN = from.BLUE = NULL;
  152.  
  153.     from.Opacity = from.Color_Map = from.Strips = 0;
  154.  
  155.     /* タグを読みます */
  156.     LOOP:
  157.     entry_num = read_SHORT(0UL);
  158.     for(i = 0; i<entry_num; i++){
  159.         tag = read_SHORT(0UL);
  160.         type= read_SHORT(0UL);
  161.         len = read_LONG(0UL);
  162.  
  163.         switch(tag){
  164.             case 0xfe :
  165.                 if( len!=1 ) goto UNREADABLE;
  166.                 from.New_Subfile_Type = read_VALUE( type,0UL );
  167.                 break;
  168.  
  169.             case 0x100:
  170.                 if( len!=1 ) goto UNREADABLE;
  171.                 from.Image_Width = read_VALUE( type,0UL );
  172.                 break;
  173.  
  174.             case 0x101:
  175.                 if( len!=1 ) goto UNREADABLE;
  176.                 from.Image_Length = read_VALUE( type,0UL );
  177.                 break;
  178.  
  179.             case 0x102:
  180.                 if( (type==SHORT_TYPE) && (len==1) ){
  181.                     from.Bits_Per_Sample = read_SHORT(0UL);
  182.                     fgetc(from.fp); fgetc(from.fp);
  183.                     continue;
  184.                     };
  185.                 if( type==SHORT_TYPE ){
  186.                     offset=ftell(from.fp); /* 現在位置のオフセットを保持 */
  187.                     fseek( from.fp, read_LONG(0UL), SEEK_SET );
  188.                     /* short*3でRGBのビット数を記録してある場合 */
  189.                     from.Bits_Per_Sample = 0;
  190.                     for( j=0; j<len; j++ )     from.Bits_Per_Sample += read_SHORT(0UL);
  191.                     if( len == 4 ) from.Opacity = 1; else from.Opacity = 0;    /* 透明度付き */
  192.                     fseek(from.fp, offset+4, SEEK_SET);    /* fpをもとに戻す */
  193.                     continue;
  194.                     };
  195.                 goto UNREADABLE;
  196.  
  197.             case 0x103:
  198.                 if( len!=1 ) goto UNREADABLE;
  199.                 from.Compression = read_VALUE( type,0UL);
  200.                 break;
  201.  
  202.             case 0x106:
  203.                 if( len!=1 ) goto UNREADABLE;
  204.                 from.Photo_Interp = read_VALUE( type,0UL);
  205.                 break;
  206.  
  207.             case 0x10a:
  208.                 if( len!=1 ) goto UNREADABLE;
  209.                 from.Fill_Order = read_VALUE( type,0UL);
  210.                 break;
  211.  
  212.             case 0x111:
  213.                 if(type!=LONG_TYPE) goto UNREADABLE;
  214.                 from.Strip_Offset = pl = MALLOC((size_t)(len*4+4));
  215.                 from.Strips=len;
  216.                 if(len==1){
  217.                     *pl=read_LONG(0UL);
  218.                     *(pl+1)=0;
  219.                     break;
  220.                     };
  221.                 offset=ftell(from.fp);
  222.                 fseek(from.fp, read_LONG(0UL), SEEK_SET);
  223.                 for(j=0; j<len; j++){
  224.                     *pl=read_LONG(0UL);
  225.                     pl++;
  226.                     };
  227.                 *pl=0; /* エンドマークの0 */
  228.                 fseek(from.fp, offset+4, SEEK_SET);
  229.                 break;
  230.  
  231.             case 0x116:
  232.                 if( len!=1 ) goto UNREADABLE;
  233.                 from.Rows_Per_Strip = read_VALUE( type,0UL);
  234.                 break;
  235.  
  236.             case 0x115:
  237.                 if( len!=1 ) goto UNREADABLE;
  238.                 from.Samples_Per_Pixel= read_VALUE( type,0UL);
  239.                 break;
  240.  
  241.             case 0x117:
  242.                 if(type!=LONG_TYPE) goto UNREADABLE;
  243.                 from.Strips_ByteCount = pl = MALLOC(len*4+4);
  244.                 from.Strips=len;
  245.                 if(len==1){
  246.                     *pl=read_LONG(0UL);
  247.                     *(pl+1)=0;
  248.                     break;
  249.                     };
  250.                 offset=ftell(from.fp);
  251.                 fseek(from.fp, read_LONG(0UL), SEEK_SET);
  252.                 for(j=0; j<len; j++){
  253.                     *pl=read_LONG(0UL);
  254.                     pl++;
  255.                     };
  256.                 *pl=0; /* エンドマークの0 */
  257.                 fseek(from.fp, offset+4, SEEK_SET);
  258.                 break;
  259.  
  260.             case 0x119:
  261.                 if( len!=1 ) goto UNREADABLE;
  262.                 from.Max_Sample_Value = read_VALUE( type,0UL);
  263.                 break;
  264.  
  265.             case 0x11a:
  266.                 if( (type!=RATIONAL_TYPE) || (len!=1) ) goto UNREADABLE;
  267.                 offset=ftell(from.fp);
  268.                 fseek(from.fp, read_LONG(0UL), SEEK_SET);
  269.                 from.X_Resolution.bunsi = read_LONG(0UL);
  270.                 from.X_Resolution.bunbo = read_LONG(0UL);
  271.                 fseek(from.fp, offset+4, SEEK_SET);
  272.                 break;
  273.  
  274.             case 0x11b:
  275.                 if( (type!=RATIONAL_TYPE) || (len!=1) ) goto UNREADABLE;
  276.                 offset=ftell(from.fp);
  277.                 fseek(from.fp, read_LONG(0UL), SEEK_SET);
  278.                 from.Y_Resolution.bunsi = read_LONG(0UL);
  279.                 from.Y_Resolution.bunbo = read_LONG(0UL);
  280.                 fseek(from.fp, offset+4, SEEK_SET);
  281.                 break;
  282.  
  283.             case 0x11c:
  284.                 if( len!=1 ) goto UNREADABLE;
  285.                 from.Planer_Config = read_VALUE( type,0UL);
  286.                 break;
  287.  
  288.             case 0x140:
  289.                 if( (type!=SHORT_TYPE) || (len%3) ) goto UNREADABLE;
  290.                 from.Color_Map=1;
  291.                 from.RED   = MALLOC( (size_t)((len/3)*2) );
  292.                 from.GREEN = MALLOC( (size_t)((len/3)*2) );
  293.                 from.BLUE  = MALLOC( (size_t)((len/3)*2) );
  294.                 k=read_LONG(0UL);
  295.                 offset=ftell(from.fp);
  296.                 fseek(from.fp , k, SEEK_SET);
  297.                 for(j=0, p=from.RED; j<len/3; j++){
  298.                     *p= read_SHORT(0UL);
  299.                     p++;
  300.                     };
  301.                 for(j=0, p=from.GREEN; j<len/3; j++){
  302.                     *p= read_SHORT(0UL);
  303.                     p++;
  304.                     };
  305.                 for(j=0, p=from.BLUE; j<len/3; j++){
  306.                     *p= read_SHORT(0UL);
  307.                     p++;
  308.                     };
  309.                 fseek(from.fp, offset, SEEK_SET);
  310.                 break;
  311.  
  312.             default   :
  313.                 UNREADABLE:
  314.                 printf("解読できないタグです。tag:%04x type:%04x len:%08lx value:%08lX\n",tag,type,len,read_LONG(0UL) );
  315.             };
  316.         };
  317.  
  318.     if( offset=read_LONG(0UL) ){
  319.         fseek(from.fp, offset, SEEK_SET);
  320.         goto LOOP;
  321.         };
  322.  
  323.     /* パレットなしの8ビットデータに、パレットを付ける */
  324.     if( (from.Bits_Per_Sample==8) && (from.Color_Map==0) ){
  325.         from.RED  = table_RED;
  326.         from.GREEN= table_GREEN;
  327.         from.BLUE = table_BLUE;
  328.         };
  329.  
  330.     /* Rows_Per_Strip が省略されてるとき。 */
  331.     if( from.Rows_Per_Strip == 0 ){
  332.         from.Rows_Per_Strip = from.Image_Length;
  333.         from.Strips_ByteCount = MALLOC(4);
  334.         *from.Strips_ByteCount = 
  335.             (UL_ from.Image_Width * UL_ from.Image_Length * UL_ from.Bits_Per_Sample) / 8UL;
  336.         /* Rows Per Strip の設定されてないLZWがあるのか? */
  337.         if( from.Compression == 5 )
  338.             puts("*注意*  このTIFFを変換できるかは、不確定です。");
  339.         }
  340.  
  341.     return;
  342. }
  343.  
  344.  
  345.  
  346. /*
  347. 複数ブロック化されているデータも、単一ブロックに見せかけて出力。
  348. エンドコードは256
  349. */
  350. unsigned short read_Gdata(void)
  351. {
  352.     static unsigned long strip_bytes=0;    /* current strip で読んだバイト数 */
  353.     static unsigned int  strip=0;    /* current strip number */
  354.     static unsigned long offset, backup_offset;
  355.     static unsigned long stack_bytes=0;    /* RAMに入ってるバイト数 */
  356.     static unsigned char *add,*pc;
  357.     static int INIT = 0;
  358.     unsigned short ret;
  359.     unsigned long bytes;
  360.  
  361.     /* Initialize */
  362.     if( INIT==0 ){
  363.         offset=*from.Strip_Offset;
  364.         if( from.Compression == 5 ){
  365.             if( from.Bits_Per_Sample == 12 )
  366.                 bytes = from.Image_Width * from.Rows_Per_Strip * 2;
  367.             else
  368.                 bytes = from.Image_Width * from.Rows_Per_Strip * (from.Bits_Per_Sample/8UL);
  369.             pc=add=MALLOC( bytes );
  370.             }
  371.         else
  372.             pc=add=MALLOC((size_t)TEMP_SIZE);
  373.         stack_bytes = 0;
  374.         INIT = 1;
  375.         };
  376.  
  377.     if( from.Compression == 5 ) goto LZW;
  378.  
  379.     if(stack_bytes==0){    /* ディスクから読む必要がある */
  380.         backup_offset=ftell(from.fp);    /* 現在のファイルポインタの保存 */
  381.         fseek(from.fp, offset, SEEK_SET);
  382.         bytes=TEMP_SIZE;
  383.         pc=add;
  384.  
  385.         LOOP:
  386.         if( from.Strips<=strip ) goto XXX;
  387.         if( bytes>= *(from.Strips_ByteCount+strip)-strip_bytes ){
  388.             fread(pc, *(from.Strips_ByteCount+strip)-strip_bytes, 1, from.fp);
  389.             pc += *(from.Strips_ByteCount+strip)-strip_bytes;
  390.             stack_bytes += *(from.Strips_ByteCount+strip)-strip_bytes;
  391.             bytes -= *(from.Strips_ByteCount+strip)-strip_bytes;
  392.             strip++;
  393.             strip_bytes=0;
  394.             fseek(from.fp, *(from.Strip_Offset+strip), SEEK_SET);
  395.             goto LOOP;
  396.             }
  397.         else
  398.             if(bytes){
  399.                 fread(pc, bytes, 1, from.fp);
  400.                 strip_bytes+=bytes;
  401.                 stack_bytes+=bytes;
  402.                 }
  403.         XXX:
  404.         offset=ftell(from.fp);
  405.         fseek(from.fp, backup_offset, SEEK_SET);
  406.         printf("\rRead %lu bytes",stack_bytes);
  407.         pc=add;
  408.  
  409.         if(stack_bytes==0){    /* それでもRAMにデータがない */
  410.             free(add);
  411.             return(256);
  412.             };
  413.         }
  414.  
  415.     ret=*pc;
  416.     pc++;
  417.     stack_bytes--;
  418.     return(ret);
  419.  
  420.     LZW:    /* 圧縮ファイル */
  421.     if( stack_bytes == 0 ){
  422.         backup_offset = ftell(from.fp);
  423.         stack_bytes = uncompress(add);
  424.         fseek(from.fp, backup_offset, SEEK_SET);
  425.         printf(" %lu bytes\r",stack_bytes);
  426.         if( stack_bytes == 0 ) return(256);
  427.         pc = add;
  428.         }
  429.  
  430.     ret = *pc;
  431.     pc++;
  432.     stack_bytes--;
  433.     return(ret);
  434. }
  435.